#pragma once
#include <string>
#include <stdint.h>
#include "mysql.h"

struct MySqlRow 
{
public:
    bool     IsValid();
    int      GetFieldCount();
    int      GetFieldLength(int fileld);
    bool     GetInt(int fileld, int& value);
    bool     GetUint(int fileld, uint32_t& value);
    bool     GetInt64(int fileld, int64_t& value);
    bool     GetUInt64(int fileld, uint64_t& value);
    bool     GetFloat(int fileld, float& value);
    bool     GetUchar(int fileld, uint8_t& value);
    bool     GetShort(int fileld, short& value);
    bool     GetUshort(int fileld, uint16_t& value);
    bool     GetString(int fileld, char* Buf, uint32_t BufSize);
    bool     GetBinary(int fileld, char* Buf, uint32_t BufSize, uint32_t& Length);
    operator bool() { return IsValid(); }

    bool     IsLegalNumberFileld(int fileld) 
	{
        if (!IsValid() || fileld >= m_fieldCount
            || m_queryRow[fileld] == NULL
            || m_queryRow[fileld][0] == 0) 
		{
            return false;
        }
        return true;
    }

protected:
    int             m_fieldCount;
    MYSQL_ROW       m_queryRow;
    unsigned long*  m_fieldLength;

public:
    MySqlRow();
    MySqlRow(MYSQL_RES* mysqlResult, int filedCount);
    ~MySqlRow();
};

class MysqlConnector;
class MySqlResult 
{
public:
    bool         FetchResult(MysqlConnector* connector);
    bool         SetMySqlResult(MYSQL_RES* mysqlResult, int affectedRows = 0);
    bool         Release();
    bool         IsValid() { return m_mysqlRes != nullptr; }
    int          GetRowCount() { return (int)mysql_num_rows(m_mysqlRes); }
    int          GetFieldCount() { return mysql_num_fields(m_mysqlRes); }
    int          GetAffectedRows() { return m_affectedRows; }
    MySqlRow     GetNextRow() { return MySqlRow(m_mysqlRes, m_fieldCount); }
    MYSQL_FIELD* GetFieldsDesc() { return mysql_fetch_fields(m_mysqlRes); }
    operator     bool() { return IsValid(); }

protected:
    MYSQL_RES* m_mysqlRes;
    int        m_fieldCount;
    int        m_affectedRows;
public:
    MySqlResult();
    MySqlResult(MYSQL_RES* mysqlResult, int affectedRows = 0);
};

class MySqlSafeResult : public MySqlResult 
{
public:
    MySqlSafeResult() {}
    MySqlSafeResult(MYSQL_RES* mysql_result, int affected_rows = 0) : MySqlResult(mysql_result, affected_rows) {}
    MySqlSafeResult(const MySqlResult &rs) : MySqlResult(rs) {}
    ~MySqlSafeResult() { Release(); }
};
